/**
  ******************************************************************************
  * @file    event.h
  * @author  Dragon.Chen
  * @version V1.0.0
  * @date    12-25-2014
  * @brief   事件处理
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2014 上海今中网络科技有限公司 </center></h2>
  ******************************************************************************
  */

#include "event.h"

int                    *VPNPortCount;
sqlite3                *dbHandle;
///****************patched by yagamishi add*************2016/02/18*******
///******************发送日志********************************************
sqlite3                *ZDLogDbHandle;
///*************************************************************************
X509_CRL               *CertRevokedList;
X509_STORE             *RootCertStore;
SOCK_BUFFER_MANAGE_T    SockBufferManage;
CERTIFICATE_MANAGE_T    CertificateManage;
CLIENT_DATA_MANAGE_T    ClientDataManage;
///
int                     PreAndroidTypeDoor = 1;                         ///表示不检查

/**
  * @brief  认证版本号
  * @param  arg1:用户数据  arg2:请求数据
  * @retval RETURN_SUCCESS
  */
int handle_version(CLIENT_DATA_T *clientData, char *msg)
{
    /// android
    if (start_with(msg, "ANDROID") == 1)
    {
        if (strcmp(msg+8, ServerConfig.androidFVersion) < 0)
            clientData->fileInfo.filefd = 1;  /* update */
        else
            clientData->fileInfo.filefd = 0;  /* noupdate */
    }
    /// window
    else
    {
        if (strcmp(msg+3, ServerConfig.windowFVersion) < 0)
            clientData->fileInfo.filefd = 1;  /* update */
        else
            clientData->fileInfo.filefd = 0;  /* noupdate */
    }

    return RETURN_SUCCESS;
}

///****************patched by yagamishi add*************2016/02/18*******
///******************发送日志********************************************
/**
  * @brief  终端加固日志写入数据库并按要求是否把用户T下线
  * @param  arg1:用户数据  arg2:请求数据
  * @retval RETURN_SUCCESS
  */
int zdjg_write_to_db(CLIENT_DATA_T *clientData, char *msg)
{
    get_loginfo_form_buff(msg);
    get_loginfo_form_local(clientData->commonName);
    get_log_to_sql();
    return RETURN_SUCCESS;
}
///**********************************************************************


/**
  * @brief  认证证书是否合法
  * @param  arg1:用户数据
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
int verify_certificate(CLIENT_DATA_T *clientData)
{
#ifdef  ENABLE_NO_CERT
        return RETURN_SUCCESS;
#endif // ENABLE_NO_CERT
    int              result      = RETURN_FAILURE;
    u_char          *contextPtr  = NULL;
	X509            *mycert      = NULL;
    X509_STORE_CTX  *context     = NULL;
    CERTIFICATE_T   *certificate = (CERTIFICATE_T *)clientData->sockBuffer;

    /// 获取用户证书
    contextPtr = certificate->buffer + 4;
    /* If the call is successful *_ptr is incremented to the byte following the parsed data */
    if ((mycert = d2i_X509_AUX(NULL, (const u_char **)&contextPtr, certificate->bufferLength-4)) == NULL)
    {
        GetLastSslErrorMessage(LOG_ERROR, "d2i_X509_AUX");
        goto cleanup;
    }

    /// 认证证书
    if ((context = X509_STORE_CTX_new()) == NULL)
        goto cleanup;

    if (X509_STORE_CTX_init(context, RootCertStore, mycert, NULL) != 1)
    {
        goto cleanup;
    }

    if ( X509_verify_cert(context) != 1)
    {
        MSG_DEBUG("Certificate is invalid! [verify function error code is ]:  %d",X509_STORE_CTX_get_error(context));
        goto cleanup;
    }

	result = RETURN_SUCCESS;

cleanup:
    if (result == RETURN_FAILURE)
        MSG_DEBUG("Certificate is invalid!");
	if (mycert)
		X509_free(mycert);
	if (context)
		X509_STORE_CTX_cleanup(context);
	if (context)
		X509_STORE_CTX_free(context);
	return result;
}

/**
  * @brief  认证证书是否过期
  * @param  arg1:用户数据  arg2:请求数据
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
int verify_certificate_revoke_list(CLIENT_DATA_T *clientData, char *msg)
{
    //由于解决sm格式证书的问题，所以使用了gmssl库，gmssl库这里编译不过去，所以使用的是默认返回真值
//    int           i;
//    int           nRevokedCert;
//    char         *ptr    = NULL;
//    X509_REVOKED *revoked= NULL;
//
//    /// 获取被吊销的总人数
//    nRevokedCert = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(CertRevokedList));
//    for (i=0; i<nRevokedCert; i++)
//    {
//        revoked = (X509_REVOKED *)sk_X509_REVOKED_value(X509_CRL_get_REVOKED(CertRevokedList), i);
//        ptr = i2s_ASN1_INTEGER(NULL, &(revoked->serialNumber));
//
//        if (streql(msg, ptr))
//        {
//            OPENSSL_free(ptr);
//            MSG_DEBUG("Certificate has been revoked!");
//            return RETURN_FAILURE;
//        }
//        OPENSSL_free(ptr);
//    }

    return RETURN_SUCCESS;
}

/**
  * @brief  处理用户登录约束:
  *         S1:如果用户信息表无该用户，添加该用户到信息表，添加默认规则(确保有该用户信息和规则信息)
  *         S2:查询数据库，登录次数大于0，根据规则文件更新规则表(确保去除测试次数)
  *         S3:根据是否需要认证，认证该用户，成功更新用户信息，将用户写入在线表
  * @param  arg1:loginBind
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
static int handle_login_constraint(const LOGIN_BIND_T *loginBind, char pmos)
{
#define  INBUF_LENGTH                     256
#define OUTBUF_LENGTH                     128



    int           rows                     = 0;
    int           cols                     = 0;
    int           organization             = 0;
    int           institution              = 0;
    int           retval                   = RETURN_FAILURE;
    char         *errmsg                   = NULL;
    char        **result                   = NULL;
    char          sqlBuffer[SQL_BUFLEN]    = {0};
    char          inBuffer[INBUF_LENGTH]   = {0};
    char          outBuffer[OUTBUF_LENGTH] = {0};
    const char   *pmos_src                 = "PMOS";
    //const char   *hWare_Phone              = "Phone";
    //const char   *hWare_phone_old          = "Android";
    const char   *hWare_PC                 = "PC";
    int           pmos_tmp                 = 0;

#define URGENT_DATABASE
#undef  URGENT_DATABASE
#ifdef  URGENT_DATABASE
        retval = 0;
        goto urgent_label;

#endif // URGENT_DATABASE
    MSG_DEBUG("[handle_login_constraint]  begin!");
    RULE_CONFIG_T localRuleConfig;
    //MSG_DEBUG("[handle_login_constraint:pmos] %d!",pmos);
    //MSG_DEBUG("[handle_login_constraint:hardware platform is %s]",loginBind->hardwarePlatform);
    ///判断硬件平台是否需要约束
    if(pmos)
    {
        #define EVENT_FALSE -1
        if(EVENT_FALSE == contains((const char*)loginBind->hardwarePlatform, hWare_PC))//不包含pc认证
        {
                MSG_DEBUG("[handle_login_constraint:hardwarePlatform should be constraint]");
                pmos_tmp = contains((const char*)(loginBind->OSVersion), pmos_src);
                MSG_DEBUG("[handle_login_constraint:pmos_tmp] %d!",pmos_tmp);
                if(pmos_tmp == -1)
                    goto finish;

        }
    }

    /// 查询用户信息表
    snprintf(sqlBuffer, SQL_BUFLEN, "SELECT * FROM MPSInfo "
                                    "WHERE userName = \'%s\'", loginBind->commomName);
    if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
    {
        MSG(LOG_ERROR, "[handle_login_constraint:query_user_info] %s!", errmsg);
        sqlite3_free(errmsg);
        goto finish;
    }

    /// 用户不在该表中
    if (rows == 0)
    {
        /* 获取用户名首字母 */
        strcpy(inBuffer, loginBind->commomName);
        UTF8_to_GB2312(inBuffer, strlen(inBuffer), outBuffer, OUTBUF_LENGTH);
        ZeroMemory(inBuffer, INBUF_LENGTH);
        get_firstcharset_from_pinyin(inBuffer, (u_char *)outBuffer, strlen(outBuffer));

        /* 将用户数据插入数据库 */
        InsertUserInformation();

        /* 设置默认规则 */
        GenerateDefaultRules();

        /* 插入组织 */
        ZeroMemory(sqlBuffer, SQL_BUFLEN);
        snprintf(sqlBuffer, SQL_BUFLEN, "SELECT usergroupinside FROM usergroupall "
                                        "WHERE usergroup_name=\'组织-%s\' AND autoadd = 1",
                                        loginBind->organization);
        if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
        {
            MSG(LOG_ERROR, "[handle_login_constraint:query_organization_info] %s!", errmsg);
            sqlite3_free(errmsg);
            goto finish;
        }
        if (rows == 1)
        {
            organization = 1;
            /* 保存组织组名 */
            ZeroMemory(inBuffer, INBUF_LENGTH);
            strcpy(inBuffer, result[1]);
            FreeQueryDataFromDatabase(result);

            /* 查询用户的userId */
            ZeroMemory(sqlBuffer, SQL_BUFLEN);
            snprintf(sqlBuffer, SQL_BUFLEN, "SELECT userId FROM MPSInfo "
                                            "WHERE userName = \'%s\'", loginBind->commomName);
            if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
            {
                MSG(LOG_ERROR, "[handle_login_constraint:query_organization_info] %s!", errmsg);
                sqlite3_free(errmsg);
                goto finish;
            }
            if (rows == 1)
            {
                ZeroMemory(sqlBuffer, SQL_BUFLEN);
                snprintf(sqlBuffer, SQL_BUFLEN, "INSERT INTO %s(userId) VALUES (\'%s\')", inBuffer/*组名*/, result[1]/*userId*/);
                FreeQueryDataFromDatabase(result);
                if (InsertDataIntoDatabase(dbHandle, sqlBuffer, errmsg) != SQLITE_OK)
                {
                    MSG(LOG_ERROR, "[handle_login_constraint:import_user_info] %s!", errmsg);
                    sqlite3_free(errmsg);
                    goto finish;
                }
            }
            else
            {
                organization = 0;
            }
        }
        else
        {
            organization = 0;
        }

        /* 插入机构 */
        ZeroMemory(sqlBuffer, SQL_BUFLEN);
        snprintf(sqlBuffer, SQL_BUFLEN, "SELECT usergroupinside FROM usergroupall "
                                        "WHERE usergroup_name=\'机构-%s\' AND autoadd = 1",
                                        loginBind->institution);
        if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
        {
            MSG(LOG_ERROR, "[handle_login_constraint:query_institute_info] %s!", errmsg);
            sqlite3_free(errmsg);
            goto finish;
        }
        if (rows == 1)
        {
            institution = 1;
            /* 保存机构组名 */
            ZeroMemory(inBuffer, INBUF_LENGTH);
            strcpy(inBuffer, result[1]);
            FreeQueryDataFromDatabase(result);

            /* 查询用户的userId */
            ZeroMemory(sqlBuffer, SQL_BUFLEN);
            snprintf(sqlBuffer, SQL_BUFLEN, "SELECT userId FROM MPSInfo "
                                            "WHERE userName = \'%s\'", loginBind->commomName);
            if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
            {
                MSG(LOG_ERROR, "[handle_login_constraint:query_institute_info] %s!", errmsg);
                sqlite3_free(errmsg);
                goto finish;
            }
            if (rows == 1)
            {
                ZeroMemory(sqlBuffer, SQL_BUFLEN);
                snprintf(sqlBuffer, SQL_BUFLEN, "INSERT INTO %s(userId) VALUES (\'%s\')", inBuffer/*组名*/, result[1]/*userId*/);
                FreeQueryDataFromDatabase(result);
                if (InsertDataIntoDatabase(dbHandle, sqlBuffer, errmsg) != SQLITE_OK)
                {
                    MSG(LOG_ERROR, "[handle_login_constraint:import_user_info] %s!", errmsg);
                    sqlite3_free(errmsg);
                    goto finish;
                }
            }
            else
            {
                institution = 0;
            }
        }
        else
        {
            institution = 0;
        }

        /* 启动PHP程序 */
        if ((organization == 0 && institution == 0) || ServerConfig.appType == 2 || ServerConfig.appType == 4)
        {
            ;
        }
        else
        {
            if (organization == 1)
            {
                MSG(LOG_ERROR, "/sonicom/php5/bin/php /sonicom/vpn/bin/autoaddgroup.php organization");
                snprintf(inBuffer, INBUF_LENGTH,
                     "/sonicom/php5/bin/php /sonicom/vpn/bin/autoaddgroup.php \"%s\" \"组织-%s\"",
                     loginBind->commomName, loginBind->organization);
                system(inBuffer);
            }
            if (institution == 1)
            {
                MSG(LOG_ERROR, "/sonicom/php5/bin/php /sonicom/vpn/bin/autoaddgroup.php institution");
                MSG(LOG_ERROR, "[handle_login_constraint:import_user_info]");
                snprintf(inBuffer, INBUF_LENGTH,
                     "/sonicom/php5/bin/php /sonicom/vpn/bin/autoaddgroup.php \"%s\" \"机构-%s\"",
                     loginBind->commomName, loginBind->institution);
                system(inBuffer);
            }
        }
    }
    else
    {
        FreeQueryDataFromDatabase(result);
    }

    /// 查询规则信息
    ZeroMemory(sqlBuffer, SQL_BUFLEN);
    snprintf(sqlBuffer, SQL_BUFLEN, "SELECT rulesCN, rulesSN, rulesHardwarePlatform, rulesHardwareSn, "
                                    "rulesOSVersion, rulesPhoneNumber, rulesClientVersion, rulesTestCount, "
                                    "rulesDoVerify FROM VpnuserRules "
                                    "WHERE rulesCN = \'%s\'", loginBind->commomName);
    if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
    {
        MSG(LOG_ERROR, "[handle_login_constraint:query_VpnuserRuless_info] %s!", errmsg);
        sqlite3_free(errmsg);
        goto finish;
    }
    if (rows == 1)
    {
        MSG(LOG_ERROR, "11111111111111111111111111111111111111111111111");
          /* rows = 1 cols = 9 0~8：字段  9~17数值 */
        localRuleConfig.commomName       =  ((strlen(result[9])  == 0) || streql(result[9],  "null")) ? 0 : 1;
        localRuleConfig.serialNumber     =  ((strlen(result[10]) == 0) || streql(result[10], "null")) ? 0 : 1;
        localRuleConfig.hardwarePlatform =  ((strlen(result[11]) == 0) || streql(result[11], "null")) ? 0 : 1;
        localRuleConfig.hardwareSN       =  ((strlen(result[12]) == 0) || streql(result[12], "null")) ? 0 : 1;
        localRuleConfig.OSVersion        =  ((strlen(result[13]) == 0) || streql(result[13], "null")) ? 0 : 1;
        localRuleConfig.phoneNumber      =  ((strlen(result[14]) == 0) || streql(result[14], "null")) ? 0 : 1;
        localRuleConfig.clientVersion    =  ((strlen(result[15]) == 0) || streql(result[15], "null")) ? 0 : 1;
        localRuleConfig.nLogin           =  atoi(result[16]);
        localRuleConfig.verify           =  atoi(result[17]);
        FreeQueryDataFromDatabase(result);

        /* 根据规则文件更新规则表 */
        if (localRuleConfig.nLogin > 0)
        {
            ZeroMemory(sqlBuffer, SQL_BUFLEN);
            snprintf(sqlBuffer, SQL_BUFLEN,
                "UPDATE VpnuserRules SET "
                "rulesSN = \'%s\', "
                "rulesHardwarePlatform = \'%s\', "
                "rulesHardwareSn    = \'%s\', "
                "rulesOSVersion = \'%s\', "
                "rulesPhoneNumber = \'%s\', "
                "rulesClientVersion = \'%s\', "
                "rulesTestCount = \'%c\' "
                "WHERE rulesCN = \'%s\'",
                localRuleConfig.serialNumber     ? loginBind->serialNumber     : "",
                localRuleConfig.hardwarePlatform ? loginBind->hardwarePlatform : "",
                localRuleConfig.hardwareSN       ? loginBind->hardwareSN       : "",
                localRuleConfig.OSVersion        ? loginBind->OSVersion        : "",
                localRuleConfig.phoneNumber      ? loginBind->phoneNumber      : "",
                localRuleConfig.clientVersion    ? loginBind->clientVersion    : "",
                ServerConfig.verify              ? localRuleConfig.nLogin+'0'-1 : localRuleConfig.nLogin+'0',
                loginBind->commomName );
            if (UpdateDataFromDatabase(dbHandle, sqlBuffer, errmsg) != SQLITE_OK)
            {
                MSG(LOG_ERROR, "[handle_login_constraint:update_rule_info] %s!", errmsg);
                sqlite3_free(errmsg);
                goto finish;
            }
        }

        /// 认证用户
        if (ServerConfig.verify == 0)
        {   /* 无需认证所有用户 */
            retval = RETURN_SUCCESS;
            UpdateUserInformation();
            goto finish;
        }
        else
        {   /* 无需认证单个用户 */
            if (localRuleConfig.verify == 0)
            {
                retval = RETURN_SUCCESS;
                UpdateUserInformation();
                goto finish;
            }
            else
            {   /* 认证当前用户 */
                ZeroMemory(sqlBuffer, SQL_BUFLEN);
                snprintf(sqlBuffer, SQL_BUFLEN,
                         "SELECT rulesSN, rulesHardwarePlatform, rulesHardwareSn, rulesOSVersion, "
                         "rulesPhoneNumber, rulesClientVersion FROM VpnuserRules "
                         "where rulesCN = \'%s\'",
                         loginBind->commomName  );
                if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
                {
                    MSG(LOG_ERROR, "[handle_login_constraint:query_rule_info] %s!", errmsg);
                    sqlite3_free(errmsg);
                    goto finish;
                }
                if (rows == 1)
                {
                    if (VerifySpecifiedField())
                    {   /* 认证成功,更新数据库 */
                        FreeQueryDataFromDatabase(result);
                        UpdateUserInformation();
                        retval = RETURN_SUCCESS;
                    }
                }
            }
        }
    }
    else
    {
        /* existing just for preciseness */
        GenerateDefaultRules();
        UpdateUserInformation();
        retval = RETURN_SUCCESS;
    }

finish:
        //****************patched by yagamishi add*************2015/10/23*******
        //******************白名单*****************************
        MSG_DEBUG("Whitelist %d",ServerConfig.whiteList);
        if(ServerConfig.whiteList == 1)
        {
            ZeroMemory(sqlBuffer, SQL_BUFLEN);
            snprintf(sqlBuffer, SQL_BUFLEN, "SELECT * from WhiteList WHERE userName  = \'%s\'", loginBind->commomName);
            if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
            {
                MSG(LOG_ERROR, "[handle_login_constraint:query_WhiteList] %s!", errmsg);
                sqlite3_free(errmsg);
            }
            if (rows < 1){
                retval = RETURN_FAILURE;
            }
        }
        //*********************************************************************
        //****************patched by yagamishi add*************2015/10/28*******
        //******************黑名单*****************************
        MSG_DEBUG("Blacklist %d",ServerConfig.blackList);
        if(ServerConfig.blackList == 1)
        {
            ZeroMemory(sqlBuffer, SQL_BUFLEN);
            snprintf(sqlBuffer, SQL_BUFLEN, "SELECT * from BlackList WHERE userName  = \'%s\'", loginBind->commomName);
            if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
            {
                MSG(LOG_ERROR, "[handle_login_constraint:query_BlackList] %s!", errmsg);
                sqlite3_free(errmsg);
            }
            if (rows >= 1){
                retval = RETURN_FAILURE;
            }
        }
        //*********************************************************************
        /* 记录日志 */
        MSG_DEBUG("worker[%d]:%s:%s %s",
                   WorkerProcess[WorkerProcessIndex].pid,
                   loginBind->commomName, loginBind->serialNumber, (retval < 0) ?
                   "Fail to pass the the verification!" : "Pass the verififcation successfully!");

        /// 将用户登录时间和状态数据库

//urgent_label:
        if (retval == 0)
        {
            char timeBuf[32] = {0};
            ZeroMemory(sqlBuffer, SQL_BUFLEN);
            snprintf(sqlBuffer, SQL_BUFLEN,
                     "UPDATE MPSInfo SET processId = %d, loginState = \'1\', userLoginTime = \'%s\' "
                     "WHERE userName = \'%s\'",
                     WorkerProcess[WorkerProcessIndex].pid,
                     get_system_date(timeBuf, 1),
                     loginBind->commomName);

            if (UpdateDataFromDatabase(dbHandle, sqlBuffer, errmsg) != SQLITE_OK)
            {
                MSG(LOG_ERROR, "[handle_login_constraint:update_user_login_info] %s!", errmsg);
                sqlite3_free(errmsg);
                retval = RETURN_FAILURE;
            }
        }
urgent_label:

     MSG_DEBUG("[handle_login_constraint]  end!");
    return retval;
}

/**
  * @brief  检查用户绑定约束
  * @param  arg1:用户数据  arg2:请求数据
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
int verify_bind_constraint(CLIENT_DATA_T *clientData, char *msg, char pmos)
{
    char           *savep;
    LOGIN_BIND_T    loginBind;

    loginBind.serialNumber     = strtok_r(msg,  ":", &savep);
    loginBind.commomName       = strtok_r(NULL, ":", &savep);
    loginBind.province         = strtok_r(NULL, ":", &savep);
    loginBind.city             = strtok_r(NULL, ":", &savep);
    loginBind.organization     = strtok_r(NULL, ":", &savep);
    loginBind.institution      = strtok_r(NULL, ":", &savep);
    loginBind.email            = strtok_r(NULL, ":", &savep);
    loginBind.hardwarePlatform = strtok_r(NULL, ":", &savep);
    loginBind.hardwareSN       = strtok_r(NULL, ":", &savep);
    loginBind.OSVersion        = strtok_r(NULL, ":", &savep);
    loginBind.phoneNumber      = strtok_r(NULL, ":", &savep);
    loginBind.clientVersion    = strtok_r(NULL, ":", &savep);
    //****************patched by yagamishi add*************2016/02/04*******
    loginBind.androidType      = strtok_r(NULL, ":", &savep);  //添加android类型显示
    //*********************************************************************

    clientData->commonName = strdup(loginBind.commomName);
    if (clientData->commonName == NULL)
        return RETURN_FAILURE;

    return handle_login_constraint(&loginBind, pmos);
}


//****************patched by yagamishi add*************2015/8/17*******
/************************************ iptables启动 ************************************/
/**
  * @brief  启动iptables，登陆成功后的用户所有
  * @param  arg1:用户数据
  * @retval NULL
  */
void generate_iptables(CLIENT_DATA_T *clientData)
{
		char dotip[16]          = {0};
		char buffer[SQL_BUFLEN] = {0};
    clientData->iptableFlag = 1;
    valip_to_dotip(dotip, clientData->ipAddress);
    snprintf(buffer, SQL_BUFLEN,
            "iptables -A STUNNELDEFINED -s %s/32 -p tcp -j TCP_ALLOWED; "
            "iptables -A STUNNELDEFINED -s %s/32 -j ACCEPT", dotip, dotip);
    system(buffer);
}
//*********************************************************************

/************************************ 生成openvpn规则 ************************************/
/**
  * @brief  生成openvpn配置文件
  * @param  arg1:用户数据  arg2:请求数据
  * @retval NULL
  */
int generate_openvpn_config(CLIENT_DATA_T *clientData, char *msg)
{
    int i, temp;
    //char dotip[16]          = {0};
    //char buffer[SQL_BUFLEN] = {0};

    //****************patched by yagamishi del**********2015/8/17***********
                    /// 启动iptable
    /*clientData->iptableFlag = 1;
    valip_to_dotip(dotip, clientData->ipAddress);
    snprintf(buffer, SQL_BUFLEN,
            "iptables -A STUNNELDEFINED -s %s/32 -p tcp -j TCP_ALLOWED; "
            "iptables -A STUNNELDEFINED -s %s/32 -j ACCEPT", dotip, dotip);
    system(buffer);
    */

    //*********************************************************************
    MSG_DEBUG("generate_openvpn_config event11");
    temp = VPNPortCount[0];
    clientData->vpnPortIndex = 0;
    for (i=1; i<ServerConfig.nCPU; i++)
    {
        if (temp > VPNPortCount[i])
        {
            temp = VPNPortCount[i];
            clientData->vpnPortIndex = i;
        }
    }
    VPNPortCount[clientData->vpnPortIndex++]++;  /* 引用时index减1 */
    MSG_DEBUG("generate_openvpn_config event22");
    return 0;
}

/************************************ 生成stunnel规则 ************************************/
/**
  * @brief  生成默认的规则信息
  * @param  arg1:clientData  arg2:sqlBuffer
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
static int generate_default_rules(CLIENT_DATA_T *clientData, char *sqlBuffer)
{
    int     i           = 0;
    int     memoryCount = 0;
    int     rows        = 0;
    int     cols        = 0;
    int     retval      = RETURN_FAILURE;
    char   *errmsg      = NULL;
    char  **result      = NULL;

    ZeroMemory(sqlBuffer, SQL_BUFLEN);
    snprintf(sqlBuffer, SQL_BUFLEN, "SELECT mobileName, clientPort, vpnPort FROM MobileService");
    if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
    {
        MSG(LOG_ERROR, "[generate_default_rules] %s!", errmsg);
        sqlite3_free(errmsg);
        goto finish;
    }

    if (rows > 0)
    {
        /************** 获取查询到的数据的大小 */
        for (i=cols; i<((rows+1) * cols); i++)  // i = cols去除关键字段
            memoryCount += (strlen(result[i]) + 1);
        clientData->fileInfo.buffer = (u_char *)calloc(strlen(StunnelConfig) + memoryCount + 2, 1);
        if (clientData->fileInfo.buffer == NULL)
            goto finish;

        strcat((char *)clientData->fileInfo.buffer, StunnelConfig);
        for (i=cols; i<((rows+1) * cols); i++)
        {
            strcat((char *)clientData->fileInfo.buffer, (i%3 ? ":" : ";"));
            strcat((char *)clientData->fileInfo.buffer, result[i]);
        }
        retval = RETURN_SUCCESS;
    }
    else
    {
        clientData->fileInfo.buffer = (u_char *)strdup(VPN_RULE_NULL);
        if (clientData->fileInfo.buffer)
            retval = RETURN_SUCCESS;
    }

finish:
    if (rows > 0)
    {
        FreeQueryDataFromDatabase(result);
    }
    return retval;
}

/**
  * @brief  生成指定的规则信息
  * @param  arg1:clientData  arg2:sqlBuffer  arg3:type(user/user group)  arg4:userId
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
static int generate_specified_rules(CLIENT_DATA_T *clientData, char *sqlBuffer, int type, unsigned long userId)
{
    int     i           = 0;
    int     memoryCount = 0;
    int     rows        = 0;
    int     cols        = 0;
    int     retval      = RETURN_FAILURE;
    char   *errmsg      = NULL;
    char  **result      = NULL;

    ZeroMemory(sqlBuffer, SQL_BUFLEN);
    snprintf(sqlBuffer, SQL_BUFLEN, "SELECT Mobile_mobileContent FROM tb_Mobile "
                                    "WHERE Mobile_userType = %d AND Mobile_userContent = %lu", type, userId);
    if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
    {
        MSG(LOG_ERROR, "[generate_specified_rules] %s!", errmsg);
        sqlite3_free(errmsg);
        goto finish;
    }

    if (rows == 1)
    {
        ZeroMemory(sqlBuffer, SQL_BUFLEN);
        snprintf(sqlBuffer, SQL_BUFLEN, "SELECT mobileName, clientPort, vpnPort FROM MobileService "
                                        "WHERE mobileid in (%s)", result[1]);
        FreeQueryDataFromDatabase(result);
        if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
        {
            MSG(LOG_ERROR, "[generate_specified_rules] %s!", errmsg);
            sqlite3_free(errmsg);
            goto finish;
        }

        if (rows > 0)
        {
            /************** 获取查询到的数据的大小 */
            for (i=cols; i<((rows+1) * cols); i++)          // i = cols去除关键字段
                memoryCount += (strlen(result[i]) + 1);
            clientData->fileInfo.buffer = (u_char *)calloc(strlen(StunnelConfig) + memoryCount + 2, 1);
            if (clientData->fileInfo.buffer == NULL)
            {
                FreeQueryDataFromDatabase(result);
                goto finish;
            }

            strcat((char *)clientData->fileInfo.buffer, StunnelConfig);
            for (i=cols; i<((rows+1) * cols); i++)
            {
                strcat((char *)clientData->fileInfo.buffer, (i%3 ? ":" : ";"));
                strcat((char *)clientData->fileInfo.buffer, result[i]);
            }

            FreeQueryDataFromDatabase(result);
            retval = RETURN_SUCCESS;
        }
        else
        {
            clientData->fileInfo.buffer = (u_char *)strdup(VPN_RULE_NULL);
            if (clientData->fileInfo.buffer)
                retval = RETURN_SUCCESS;
        }
    }
    else
    {
        clientData->fileInfo.buffer = (u_char *)strdup(VPN_RULE_NULL);
        if (clientData->fileInfo.buffer)
            retval = RETURN_SUCCESS;
    }

finish:
    return retval;
}

/**
  * @brief  查询组
  * @param  arg1:clientData  arg2:sqlBuffer  arg3: userId
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
static int query_group(CLIENT_DATA_T *clientData, char *sqlBuffer, unsigned long userId)
{
    int      i       = 0;
    int      rows    = 0;
    int      rows2   = 0;
    int      cols    = 0;
    int      retval  = RETURN_FAILURE;
    char    *errmsg  = NULL;
    char   **result1 = NULL;
    char   **result2 = NULL;

    ZeroMemory(sqlBuffer, SQL_BUFLEN);
    snprintf(sqlBuffer, SQL_BUFLEN, "SELECT usergroupall_id, usergroupinside FROM usergroupall "
                                    "WHERE stunnelused = 1");
    if (QueryDataFromDatabase(dbHandle, sqlBuffer, result1, rows, cols, errmsg) != SQLITE_OK)
    {
        MSG(LOG_ERROR, "[query_group1] %s", errmsg);
        sqlite3_free(errmsg);
        goto finish;
    }

    /// 发送所有的规则
    if (rows == 0)
    {
        retval = generate_default_rules(clientData, sqlBuffer);
    }
    else
    {
        for (i=1; i<= rows; i++)
        {
            ZeroMemory(sqlBuffer, SQL_BUFLEN);
            snprintf(sqlBuffer, SQL_BUFLEN, "SELECT * FROM %s WHERE userId = %lu", result1[2*i + 1], userId);
            if (QueryDataFromDatabase(dbHandle, sqlBuffer, result2, rows2, cols, errmsg) != SQLITE_OK)
            {
                MSG(LOG_ERROR, "[query_group2] %s", errmsg);
                sqlite3_free(errmsg);
                goto finish;
            }
            FreeQueryDataFromDatabase(result2);
            if (rows2 > 0)
            {
                retval = generate_specified_rules(clientData, sqlBuffer, 2/*user group*/, (unsigned long)atol(result1[2*i]));
                FreeQueryDataFromDatabase(result1);
                goto finish;
            }
        }

        retval = generate_default_rules(clientData, sqlBuffer);
        FreeQueryDataFromDatabase(result1);
    }

finish:
    return retval;
}

/**
  * @brief  生成stunnel配置文件
  * @param  arg1:用户数据  arg3:请求数据
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
int generate_stunnel_config(CLIENT_DATA_T *clientData, char *msg)
{
    int     rows                  = 0;
    int     cols                  = 0;
    int     retval                = RETURN_FAILURE;
    char   *errmsg                = NULL;
    char  **result                = NULL;
    char    sqlbuffer[SQL_BUFLEN] = {0};

    snprintf(sqlbuffer, SQL_BUFLEN, "SELECT userId, stunnelused FROM MPSInfo "
                                    "WHERE userName = \'%s\'", clientData->commonName);
    if (QueryDataFromDatabase(dbHandle, sqlbuffer, result, rows, cols, errmsg) != SQLITE_OK)
    {
        MSG(LOG_ERROR, "[generate_stunnel_config] %s!", errmsg);
        sqlite3_free(errmsg);
        goto finish;
    }

    if (rows == 1)
    {
        if (atoi(result[3])/*stunnelused(表字段占据一行)*/)
        {
            retval = generate_specified_rules(clientData,  sqlbuffer, 1/*user*/, atol(result[2])/*userid*/);
        }
        else
        {
            retval = query_group(clientData, sqlbuffer, atol(result[2])/*userid*/);
        }

        FreeQueryDataFromDatabase(result);
    }

finish:
    return retval;
}

/************************************ 生成utunnel规则 ************************************/
/**
  * @brief  生成默认的规则信息
  * @param  arg1:clientData  arg2:sqlBuffer
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
//*************patched by xiaohu add****2015/09/09**************//
static int generate_default_udp_rules(CLIENT_DATA_T *clientData, char *sqlBuffer)
{
    int     i           = 0;
    int     memoryCount = 0;
    int     rows        = 0;
    int     cols        = 0;
    int     retval      = RETURN_FAILURE;
    char   *errmsg      = NULL;
    char  **result      = NULL;

    ZeroMemory(sqlBuffer, SQL_BUFLEN);
    snprintf(sqlBuffer, SQL_BUFLEN, "SELECT mobileName, clientPort, vpnPort,connectNum FROM INUDP");
    if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
    {
        MSG(LOG_ERROR, "[generate_default_udp_rules] %s!", errmsg);
        sqlite3_free(errmsg);
        goto finish;
    }

    if (rows > 0)
    {
        /************** 获取查询到的数据的大小 */
        for (i=cols; i<((rows+1) * cols); i++)  // i = cols去除关键字段
            memoryCount += (strlen(result[i]) + 1);
        clientData->fileInfo.buffer = (u_char *)calloc(strlen(UtunnelConfig) + memoryCount + 2, 1);
        if (clientData->fileInfo.buffer == NULL)
            goto finish;

        strcat((char *)clientData->fileInfo.buffer, UtunnelConfig);
        for (i=cols; i<((rows+1) * cols); i++)
        {
            strcat((char *)clientData->fileInfo.buffer, (i%4 ? ":" : ";"));
            strcat((char *)clientData->fileInfo.buffer, result[i]);
        }
        retval = RETURN_SUCCESS;
    }
    else
    {
        clientData->fileInfo.buffer = (u_char *)strdup(VPN_RULE_NULL);
        if (clientData->fileInfo.buffer)
            retval = RETURN_SUCCESS;
    }

finish:
    if (rows > 0)
    {
        FreeQueryDataFromDatabase(result);
    }
    return retval;
}

/**
  * @brief  生成指定的udp规则信息
  * @param  arg1:clientData  arg2:sqlBuffer  arg3:type(user/user group)  arg4:userId
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
static int generate_specified_udp_rules(CLIENT_DATA_T *clientData, char *sqlBuffer, int type, unsigned long userId)
{
    int     i           = 0;
    int     memoryCount = 0;
    int     rows        = 0;
    int     cols        = 0;
    int     retval      = RETURN_FAILURE;
    char   *errmsg      = NULL;
    char  **result      = NULL;

    ZeroMemory(sqlBuffer, SQL_BUFLEN);
    snprintf(sqlBuffer, SQL_BUFLEN, "SELECT Mobile_mobileContent FROM tb_INUDP "
                                    "WHERE Mobile_userType = %d AND Mobile_userContent = %lu", type, userId);
    if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
    {
        MSG(LOG_ERROR, "[generate_specified_udp_rules] %s!", errmsg);
        sqlite3_free(errmsg);
        goto finish;
    }

    if (rows == 1)
    {
        ZeroMemory(sqlBuffer, SQL_BUFLEN);
        snprintf(sqlBuffer, SQL_BUFLEN, "SELECT mobileName, clientPort, vpnPort,connectNum FROM INUDP "
                                        "WHERE mobileid in (%s)", result[1]);
        FreeQueryDataFromDatabase(result);
        if (QueryDataFromDatabase(dbHandle, sqlBuffer, result, rows, cols, errmsg) != SQLITE_OK)
        {
            MSG(LOG_ERROR, "[generate_specified_udp_rules] %s!", errmsg);
            sqlite3_free(errmsg);
            goto finish;
        }

        if (rows > 0)
        {
            /************** 获取查询到的数据的大小 */
            for (i=cols; i<((rows+1) * cols); i++)          // i = cols去除关键字段
                memoryCount += (strlen(result[i]) + 1);
            clientData->fileInfo.buffer = (u_char *)calloc(strlen(UtunnelConfig) + memoryCount + 2, 1);
            if (clientData->fileInfo.buffer == NULL)
            {
                FreeQueryDataFromDatabase(result);
                goto finish;
            }

            strcat((char *)clientData->fileInfo.buffer, UtunnelConfig);
            for (i=cols; i<((rows+1) * cols); i++)
            {
                strcat((char *)clientData->fileInfo.buffer, (i%4 ? ":" : ";"));
                strcat((char *)clientData->fileInfo.buffer, result[i]);
            }

            FreeQueryDataFromDatabase(result);
            retval = RETURN_SUCCESS;
        }
        else
        {
            clientData->fileInfo.buffer = (u_char *)strdup(VPN_RULE_NULL);
            if (clientData->fileInfo.buffer)
                retval = RETURN_SUCCESS;
        }
    }
    else
    {
        clientData->fileInfo.buffer = (u_char *)strdup(VPN_RULE_NULL);
        if (clientData->fileInfo.buffer)
            retval = RETURN_SUCCESS;
    }

finish:
    return retval;
}

/**
  * @brief  查询组
  * @param  arg1:clientData  arg2:sqlBuffer  arg3: userId
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
static int query_udp_group(CLIENT_DATA_T *clientData, char *sqlBuffer, unsigned long userId)
{
    int      i       = 0;
    int      rows    = 0;
    int      rows2   = 0;
    int      cols    = 0;
    int      retval  = RETURN_FAILURE;
    char    *errmsg  = NULL;
    char   **result1 = NULL;
    char   **result2 = NULL;

    ZeroMemory(sqlBuffer, SQL_BUFLEN);
    snprintf(sqlBuffer, SQL_BUFLEN, "SELECT usergroupall_id, usergroupinside FROM usergroupall "
                                    "WHERE inudpused = 1");
    if (QueryDataFromDatabase(dbHandle, sqlBuffer, result1, rows, cols, errmsg) != SQLITE_OK)
    {
        MSG(LOG_ERROR, "[query_udp_group1] %s", errmsg);
        sqlite3_free(errmsg);
        goto finish;
    }

    /// 发送所有的规则
    if (rows == 0)
    {
        retval = generate_default_udp_rules(clientData, sqlBuffer);
    }
    else
    {
        for (i=1; i<= rows; i++)
        {
            ZeroMemory(sqlBuffer, SQL_BUFLEN);
            snprintf(sqlBuffer, SQL_BUFLEN, "SELECT * FROM %s WHERE userId = %lu", result1[2*i + 1], userId);
            if (QueryDataFromDatabase(dbHandle, sqlBuffer, result2, rows2, cols, errmsg) != SQLITE_OK)
            {
                MSG(LOG_ERROR, "[query_udp_group2] %s", errmsg);
                sqlite3_free(errmsg);
                goto finish;
            }
            FreeQueryDataFromDatabase(result2);
            if (rows2 > 0)
            {
                retval = generate_specified_udp_rules(clientData, sqlBuffer, 2/*user group*/, (unsigned long)atol(result1[2*i]));
                FreeQueryDataFromDatabase(result1);
                goto finish;
            }
        }

        retval = generate_default_udp_rules(clientData, sqlBuffer);
        FreeQueryDataFromDatabase(result1);
    }

finish:
    return retval;
}

/**
  * @brief  生成stunnel配置文件
  * @param  arg1:用户数据  arg3:请求数据
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
int generate_utunnel_config(CLIENT_DATA_T *clientData, char *msg)
{
    int     rows                  = 0;
    int     cols                  = 0;
    int     retval                = RETURN_FAILURE;
    char   *errmsg                = NULL;
    char  **result                = NULL;
    char    sqlbuffer[SQL_BUFLEN] = {0};

    snprintf(sqlbuffer, SQL_BUFLEN, "SELECT userId, inudpused FROM MPSInfo "
                                    "WHERE userName = \'%s\'", clientData->commonName);
    if (QueryDataFromDatabase(dbHandle, sqlbuffer, result, rows, cols, errmsg) != SQLITE_OK)
    {
        MSG(LOG_ERROR, "[generate_stunnel_config] %s!", errmsg);
        sqlite3_free(errmsg);
        goto finish;
    }

    if (rows == 1)
    {
        if (atoi(result[3])/*stunnelused(表字段占据一行)*/)
        {
            retval = generate_specified_udp_rules(clientData,  sqlbuffer, 1/*user*/, atol(result[2])/*userid*/);
        }
        else
        {
            retval = query_udp_group(clientData, sqlbuffer, atol(result[2])/*userid*/);
        }

        FreeQueryDataFromDatabase(result);
    }

finish:
    return retval;
}

///****************patched by yagamishi add*************2016/02/17*******
/**
  * @brief  得到checkrunningswitch.conf内容格式化
  * @param  arg1:用户数据  arg2:请求数据
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
int generate_check_running_switch_config(CLIENT_DATA_T *clientData, char *msg)
{
    clientData->fileInfo.buffer = (u_char *)calloc(strlen(checkRsInfo.twoWay)+1, 1);
    ///****************patched by yagamishi change*************2016/02/20*******
    sprintf((char *)clientData->fileInfo.buffer,"%s:%s",
            checkRsInfo.checkSleepTime,(u_char*)checkRsInfo.twoWay);
    ///**********************************************************************
    return RETURN_SUCCESS;
}
int generate_android_check_switch_config(CLIENT_DATA_T *clientData, char *msg)
{
    clientData->fileInfo.buffer = (u_char *)calloc(
    strlen(adCheckSInfo.root)+strlen(adCheckSInfo.wifi)+1, 1);
    sprintf((char *)clientData->fileInfo.buffer,"%s:%s",
            adCheckSInfo.root,
            adCheckSInfo.wifi);
    return RETURN_SUCCESS;
}
int generate_android_check_running_switch_config(CLIENT_DATA_T *clientData, char *msg)
{
    clientData->fileInfo.buffer = (u_char *)calloc(
            strlen(adCheckRsInfo.twoWay)+strlen(adCheckRsInfo.share)+
            strlen(adCheckRsInfo.bluetooth)+1, 1);
    ///****************patched by yagamishi change*************2016/02/20*******
    sprintf((char *)clientData->fileInfo.buffer,"%s:%s:%s:%s",
            adCheckRsInfo.checkSleepTime,
            adCheckRsInfo.twoWay,
            adCheckRsInfo.share,
            adCheckRsInfo.bluetooth);
    ///**********************************************************************

    return RETURN_SUCCESS;
}
///*************************************************************************

///****************patched by yagamishi add*************2016/02/26*******
/**
  * @brief  得到手机型号，然后解析是否符合手机型号需要
  * @param  arg1:用户数据  arg2:请求数据
  * @retval 成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
int generate_android_type_door_config(CLIENT_DATA_T *clientData, char *msg)
{
    int i=10;
    int retVal;
    ///解析msg,是否符合要求
    if (PreAndroidTypeDoor == 0)
    {
        srand(time(0));
        i=rand()%89+10;
        clientData->fileInfo.buffer = (u_char *)calloc(2, 1);
        sprintf((char *)clientData->fileInfo.buffer,"%d",i);
    }
    else
    {
        retVal = filter_element(msg);
        if( retVal == 1 )
        {
                ///1表示禁止登录,0表示不禁止登录
            if(FilterPhoneTypeDoorPermit == 1)
            {
                srand( time(0) );
                i = rand()%90+560;
                clientData->fileInfo.buffer = (u_char *)calloc(2, 1);
                sprintf((char *)clientData->fileInfo.buffer,"%d",i);
            }
            else
            {
                srand( time(0) );
                i = rand()%89+10;
                clientData->fileInfo.buffer = (u_char *)calloc(2, 1);
                sprintf((char *)clientData->fileInfo.buffer,"%d",i);
            }
        }
        if( retVal == 0)
        {
            if(FilterPhoneTypeDoorPermit == 0)
            {
                srand( time(0) );
                i = rand()%90+560;
                clientData->fileInfo.buffer = (u_char *)calloc(2, 1);
                sprintf((char *)clientData->fileInfo.buffer,"%d",i);
            }
            else
            {
                srand( time(0) );
                i = rand()%89+10;
                clientData->fileInfo.buffer = (u_char *)calloc(2, 1);
                sprintf((char *)clientData->fileInfo.buffer,"%d",i);
            }
        }
    }
    return RETURN_SUCCESS;
}
///*************************************************************************


//*********************************************************************
/**
  * @brief  生成utunnel配置文件
  * @param  arg1:用户数据  arg2:请求数据
  * @retval NULL
  */
//pathed by xiaohu
/*
int generate_utunnel_config(CLIENT_DATA_T *clientData, char *msg)
{
    int     i           = 0;
    int     memoryCount = 0;
    int     rows        = 0;
    int     cols        = 0;
    int     retval      = RETURN_FAILURE;
    char   *errmsg      = NULL;
    char  **result      = NULL;
    char    sqlbuffer[SQL_BUFLEN] = {0};

    snprintf(sqlbuffer, SQL_BUFLEN, "SELECT mobileName, clientPort, vpnPort, connectNum FROM INUDP");
    if (QueryDataFromDatabase(dbHandle, sqlbuffer, result, rows, cols, errmsg) != SQLITE_OK)
    {
        MSG(LOG_ERROR, "[generate_utunnel_config] %s!", errmsg);
        sqlite3_free(errmsg);
        goto finish;
    }

    if (rows > 0)
    {
        // ************* 获取查询到的数据的大小
        for (i=cols; i<((rows+1) * cols); i++)  // i = cols去除关键字段
            memoryCount += (strlen(result[i]) + 1);
        clientData->fileInfo.buffer = (u_char *)calloc(strlen(UtunnelConfig) + memoryCount + 2, 1);
        if (clientData->fileInfo.buffer == NULL)
            goto finish;

        strcat((char *)clientData->fileInfo.buffer, UtunnelConfig);
        for (i=cols; i<((rows+1) * cols); i++)
        {
            strcat((char *)clientData->fileInfo.buffer, (i%4 ? ":" : ";"));
            strcat((char *)clientData->fileInfo.buffer, result[i]);
        }
        retval = RETURN_SUCCESS;
    }
    else
    {
        clientData->fileInfo.buffer = (u_char *)strdup(VPN_RULE_NULL);
        if (clientData->fileInfo.buffer)
            retval = RETURN_SUCCESS;
    }

finish:
    if (rows > 0)
    {
        FreeQueryDataFromDatabase(result);
    }
    return retval;
}
*/
/******************* (C) COPYRIGHT 2014 上海今中网络科技有限公司 *****END OF FILE****/








